﻿/*  
 * Helix Engine
 * http://helixengine.codeplex.com/
 * 
 * Copyright (c) 2010 - 2011 Joe Hegarty
 *  
 * This source code is subject to the terms of the Microsoft Public License (Ms-PL). 
 *  
 * Redistribution and use in source and binary forms, with or without modification, 
 * is permitted provided that redistributions of the source code retain the above 
 * copyright notices and this file header. 
 * 
 * For details please see http://www.opensource.org/licenses/ms-pl.html 
 *  
 * All other rights reserved. 
 *
 */  


using System;
using System.Windows.Controls;

using HelixEngine.Exceptions;
using HelixEngine.Render;
using HelixEngine.Resources;
using HelixEngine.Maths;
using HelixEngine.Input;

namespace HelixEngine
{
    /// <remarks>
    /// Singleton representing access to the Helix Engine
    /// </remarks>
    /// <permission cref="System.Security.PermissionSet">public sealed</permission>
    public sealed class Engine 
    {
        #region Singleton

        static Engine _engineInstance = null;

        /// <summary>
        /// Initialise the Helix Engine
        /// </summary>
        /// <exception cref="AlreadyInitialisedException">
        /// Thrown when an instance of the engine has already been initialised
        /// </exception>
        public static void InitialiseEngine(Image sceneRoot)
        {
            if (_engineInstance == null)
            {
                _engineInstance = new Engine(sceneRoot);
            }
            else
            {
                throw new AlreadyInitialisedException("_engineInstance");
            }
        }

        /// <summary>
        /// Returns the active instance of the engine
        /// </summary>
        /// <returns>An instance of HelixEngine</returns>
        /// <exception cref="NotInitialisedException">
        /// Thrown when an instance of the engine does not exist
        /// </exception>
        public static Engine Get()
        {
            if (_engineInstance != null)
            {
                return _engineInstance;
            }
            else
            {
                throw new AlreadyInitialisedException("_engineInstance");
            }
        }

        #endregion

        RenderManager _renderManager = null;
        ResourceManager _resourceManager = null;
        InputManager _inputManager = null;

        /// <summary>
        /// The constructor for HelixEngine. Creates an instance of the engine
        /// </summary>
        /// <param name="sceneRoot">The root of the scene to render into</param>
        public Engine(Image sceneRoot)
        {
            _renderManager = new RenderManager(sceneRoot);
            _resourceManager = new ResourceManager();
            _inputManager = new InputManager(sceneRoot);
        }

        /// <summary>
        /// Represents the engines Render System
        /// </summary>
        public RenderManager RenderManager
        {
            get
            {
                return _renderManager;
            }
        }

        /// <summary>
        /// Represents the engines Resource System
        /// </summary>
        public ResourceManager ResourceManager
        {
            get
            {
                return _resourceManager;
            }
        }

        /// <summary>
        /// Represents the engines Input system
        /// </summary>
        public InputManager InputManager
        {
            get
            {
                return _inputManager;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="time"></param>
        public void Update(EngineTime time)
        {
            _inputManager.Update();
            _renderManager.RootScene.ExecuteQueuedWrites();
        }
    }
}
